直接操作 Vue data 中不存在的属性导致的 v

您所在的位置:网站首页 v-model 绑定数组 直接操作 Vue data 中不存在的属性导致的 v

直接操作 Vue data 中不存在的属性导致的 v

2023-09-10 15:11| 来源: 网络整理| 查看: 265

初学Vue遇到的问题,尝试了几个小时才搞明白,大佬应该一眼就能看出什么问题吧……

需要注意,不要直接在JS中操作一个Vue data对象中不存在的属性,如果同时有通过v-model绑定到该对象的不存在的属性时,会出现诡异的行为表现,console中不会报出任何 warn 或 error。

需求是,实现三个复选框,第一个复选框初始为选中状态,一开始写出来是这样的——

HTML

1 2 3 4 5 复选框 {{ box.title }}

JS

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 new Vue({ el: '#app', data () { return { checkboxes: [ { id: 1, title: 'a' }, { id: 2, title: 'b' }, { id: 3, title: 'c' } ] } }, created () { this.checkboxes[0].selected = true } })

试下效果:

 

复选框a的表现显然是异常的,点击不能成功地切换选中状态,而在点击之后再点击其他复选框,才会“有延迟地”切换状态。

为什么会这样?

尝试在created方法的末尾打印出this.checkboxes[0]——

发现 id 和 title 都变成了 getter/setter 的形式,而 selected 仍然是独立的属性。

后续查询发现,Vue 官方文档 - 深入响应式原理 的第一段话是——

当你把一个普通的 JavaScript 对象传入 Vue 实例作为 data 选项,Vue 将遍历此对象所有的属性,并使用 Object.defineProperty 把这些属性全部转为 getter/setter。Object.defineProperty 是 ES5 中一个无法 shim 的特性,这也就是 Vue 不支持 IE8 以及更低版本浏览器的原因。

在 created 方法中,我尝试直接对 Vue data 对象中的属性操作,而 v-model 需要使用 getter/setter 操作,二者即产生了冲突。

解决方式 1

在 data 中添加 selected 属性,即使初值为undefined或者null,也能够让 Vue 正确识别所有对象属性。

JS

1 2 3 4 5 6 7 8 9 data () { return { checkboxes: [ { id: 1, title: 'a', selected: undefined }, { id: 2, title: 'b', selected: undefined }, { id: 3, title: 'c', selected: undefined } ] } } 解决方式 2

在JS中操作原本不存在的属性时,使用 Vue.set(object, propertyName, value) 方法向嵌套对象添加响应式属性

JS

1 2 3 4 created () { // Vue.set 等同 this.$set this.$set(this.checkboxes[0], 'selected', true) }

#jsvue

本文标题:直接操作 Vue data 中不存在的属性导致的 v-model 绑定异常问题本文作者:iMaeGoo发布时间:2019-10-24 20:10本文链接:https://www.imaegoo.com/2019/vue-model-not-work/版权声明:本博客所有文章除特别声明外,均采用 CC BY 4.0 许可协议。转载请注明出处!

 

 

 

 

 

 

 

 

 

 

 

 

 

 

//关于props 和 v-model 和 $set ()  和 $focusUpdate() 方法的 理解和使用

1 props 

            * 1 子组件可以直接修改父组件的数组和对象,并且父组件会跟着改变,可能是因为两个数据

             *   指向同一个内存位置。

             * 2 如果直接修改string类型的惠报错

             * 3 如果修改json 数组中的item 的值的时候深度监听的时候是可以监听到的。

 2 v-model 

   一般情况下如果v-mode 绑定了一个没有被定义的属性,这个时候不可以直接修改这个属性

  可以使用        that.$set(that.detail[idx],'selected',false) 方法修改这个不存在的属性,不然会报错

3 如果是数组和对象 你 直接使用 this.arry[0] = 1 类似的操作是不会自动检测到更新的,

 1)然而你可以使用 this.$focusUpdate 方法

  强制刷新。 

  2)或者你data中的数据保存一份到自定义的变量中,然后再次 把这个变量放回去,

3) 使用推荐的方法比如 this.array.pop() 这个pop 方法会被检测到。

 

  * 4 如果是给数组对象中新增一个key 那么深度监听也监听不到

                    that.$set(that.detail[idx],'selected',false)

             *   这个方法添加对象中的一个key的值,这样同样会触发更新。 

 



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3